<?php
/**
 * @Author: Zhaojun(13040@qq.com)
 * @Date:   2018-07-11 16:40:16
 * @Last Modified by:   lianlianzan
 * @Last Modified time: 2020-12-28 13:18:06
 */

namespace app\actstar_manage\controller;
use app\common\controller\ManageBase;

class RecordRefund extends ManageBase {

	function initialize() {
		parent::initialize();
		$this->saveAndGetConfigIdentify(model('Config'), '订单退款管理', '', 'recordRefund');

		$this->activeDao = model('Active');
		$this->recordDao = model('Record');
	}

	public function index() {
		//获取订单退款列表
		list($map, $parameter) = $this->getMap();

		$count = $this->recordRefundDao->countSearch($map);
		$Page = new \org\util\PageBootstrap($count, config('PER_PAGE'), $parameter);
		$pageShow = $Page->show();
		list($refundList, $signupIds) = $this->recordRefundDao->search($map, $Page->getLimit());
		$this->assign('count', $count);
		$this->assign('pageShow', $pageShow);
		$this->assign('refundList', $refundList);

		//获取图片组
		//list($refundPictureGroup) = $this->recordRefundPictureDao->getGroupByRefundIds($ids);
		//$this->assign('refundPictureGroup', $refundPictureGroup);

		return $this->fetch();
	}

	private function getMap() {
		$map = $parameter = array();

		list($map, $parameter) = $this->getMapForUser($map, $parameter); //通用搜索

		$signup_id = input('param.signup_id', '', '', 'intval');
		if ($signup_id) {
			$map[] = ['signup_id', '=', $signup_id];
			$parameter['signup_id'] = $signup_id;
		}
		$this->assign('signup_id', $signup_id);

		$order_no = input('param.order_no', '', '', 'pwEscape');
		if ($order_no) {
			$map[] = ['order_no', 'like', '%'.$order_no.'%'];
			$parameter['order_no'] = $order_no;
		}
		$this->assign('order_no', $order_no);

		$payment_trade_no = input('param.payment_trade_no', '', 'pwEscape');
		if ($payment_trade_no) {
			$map[] = ['payment_trade_no', 'like', '%'.$payment_trade_no.'%'];
			$parameter['payment_trade_no'] = $payment_trade_no;
		}
		$this->assign('payment_trade_no', $payment_trade_no);

		$total_fee = input('param.total_fee', '', 'pwEscape');
		if ($total_fee) {
			$map[] = ['total_fee', '=', $total_fee];
			$parameter['total_fee'] = $total_fee;
		}
		$this->assign('total_fee', $total_fee);

		return array($map, $parameter);
	}

	public function refundPop() {
		$this->zzSetCsrf(); //csrf验证

		//退款渠道
		$channel = input('param.channel', '1', '', 'intval');

		if ($channel == 1) {
			$signupId = input('param.signupId', '', '', 'intval');
			if (!$signupId) {
				return $this->wapError('非法报名记录ID');
			}
		} else if ($channel == 2) {
			$refundId = input('param.refundId', '', '', 'intval');

			//获取订单退款信息
			$refundInfo = $this->recordRefundDao->getInfo($refundId);
			$signupId = $refundInfo['signup_id'];
		}

		//获取报名记录信息
		$recordInfo = $this->recordDao->getInfo($recordId);

		$this->assign("channel", $channel);
		$this->assign("refundId", $refundId);
		$this->assign("recordId", $recordId);
		$this->assign("recordInfo", $recordInfo);

		echo $this->fetch()->getContent();
	}

	public function doRefund() {
		$this->zzCheckCsrf(1); //csrf验证

		$channel = input('post.channel', '', '', 'intval');
		$refundId = input('post.refundId', '', '', 'intval');
		$recordId = input('post.recordId', '', '', 'intval');
		$refund_fee = input('post.refund_fee', '', '', 'pwEscape');
		$refund_reason = input('post.refund_reason', '', '', 'pwEscape');

		if ($channel == 1) {


		} else if ($channel == 2) {
			//获取订单退款信息
			$refundInfo = $this->recordRefundDao->getInfo($refundId);
			$recordId = $refundInfo['record_id'];
		} else {
			$this->error('非法退款渠道');
		}
		if (!$recordId) {
			$this->error('非法报名记录ID');
		}

		//获取报名记录信息
		$recordInfo = $this->recordDao->getInfo($recordId);

		if ($recordInfo['signup_status'] == 7) {
			$this->error('该报名记录已经关闭，不支持退款');
		}
		if ($refund_fee > $recordInfo['total_fee']) {
			$this->error('退款金额不能大于订单总额');
		}

		//==========支付宝和微信退款操作
		if ($recordInfo['pay_method'] == 'alipay') { //支付宝退款处理

/* *
 * 功能：支付宝手机网站alipay.trade.refund (统一收单交易退款接口)调试入口页面
 * 版本：2.0
 * 修改日期：2016-11-01
 * 说明：
 * 以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
 请确保项目文件有可写权限，不然打印不了日志。
 */

header("Content-type: text/html; charset=utf-8");

//=====组织数据
$out_trade_no = $recordInfo['order_no'];
$trade_no = $recordInfo['payment_trade_no'];
$refund_amount = $recordInfo['total_fee'];
$refund_reason = $refund_reason;
$out_request_no = $this->_build_order_no($recordInfo['uid']);

require_once EXTEND_PATH.'alipayTrade/wappay/service/AlipayTradeService.php';
require_once EXTEND_PATH.'alipayTrade/wappay/buildermodel/AlipayTradeRefundContentBuilder.php';
require EXTEND_PATH.'alipayTrade/config.php';

//商户订单号和支付宝交易号不能同时为空。 trade_no、  out_trade_no如果同时存在优先取trade_no
//商户订单号，和支付宝交易号二选一
$out_trade_no = trim($recordInfo['order_no']);

//支付宝交易号，和商户订单号二选一
$trade_no = trim($recordInfo['payment_trade_no']);

//退款金额，不能大于订单总金额
$refund_amount=trim($refund_fee);

//退款的原因说明
$refund_reason=trim($refund_reason);

//标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。
$out_request_no=trim($out_request_no);

$RequestBuilder = new \AlipayTradeRefundContentBuilder();
$RequestBuilder->setTradeNo($trade_no);
$RequestBuilder->setOutTradeNo($out_trade_no);
$RequestBuilder->setRefundAmount($refund_amount);
$RequestBuilder->setRefundReason($refund_reason);
$RequestBuilder->setOutRequestNo($out_request_no);

$Response = new \AlipayTradeService($config);
$result=$Response->Refund($RequestBuilder);

/*
object(stdClass)#26 (6) {
  ["code"]=>
  string(5) "40004"
  ["msg"]=>
  string(15) "Business Failed"
  ["sub_code"]=>
  string(19) "ACQ.TRADE_NOT_EXIST"
  ["sub_msg"]=>
  string(15) "交易不存在"
  ["refund_fee"]=>
  string(4) "0.00"
  ["send_back_fee"]=>
  string(4) "0.00"
}

*/

if ($result->code == 10000) { //退款成功
	$msg = '退款成功，'.$refund_fee.'元退款到用户支付宝';
} else { //退款失败
	$this->error('支付宝退款发生错误'.$result->sub_msg);
}

		} else if ($recordInfo['pay_method'] == 'wxpay') { //微信退款处理

/*
注意：
1.交易时间超过 1 年的订单无法提交退款；
2.支持部分退款， 部分退需要设置相同的订单号和不同的 out_refund_no。一笔退款失败后重新提交，要采用原来的 out_refund_no。总退款金额丌能超过用户实际支付金额。

微信退款错误的解决方法：http://www.cnblogs.com/txw1958/p/5221186.html
*/

//=====组织数据
$out_trade_no = $recordInfo['order_no'];
$trade_no = $recordInfo['payment_trade_no'];
$totalFee = intval($recordInfo['total_fee'] * 100);
$refundFee = intval($refund_fee * 100);
$refund_reason = $refund_reason;
$out_request_no = $this->_build_order_no($recordInfo['uid']);

$weixinAccountDao = model('weixin_manage/WeixinAccount');
$wxdb = $weixinAccountDao->getInfo(2); //昆山全知道

//支付账号初始化
define('WXDB_APPID', $wxdb['appid']);
define('WXDB_MCHID', $wxdb['mchid']);
define('WXDB_MCHKEY', $wxdb['mchkey']);
define('WXDB_APPSECRET', $wxdb['appsecret']);
define('WXDB_SSLCERT_PATH', EXTEND_PATH.'/weixin/'.$wxdb['wxnumber'].'/apiclient_cert.pem');
define('WXDB_SSLKEY_PATH', EXTEND_PATH.'/weixin/'.$wxdb['wxnumber'].'/apiclient_key.pem');

require_once EXTEND_PATH."weixin_pay/lib/WxPay.Api.php";

if (isset($recordInfo["payment_trade_no"]) && $recordInfo["payment_trade_no"] != "") { //微信订单号
	//print_r($recordInfo['payment_trade_no']);
	//print_r($recordInfo['total_fee']);
	$input = new \WxPayRefund();
	$input->SetTransaction_id($recordInfo['payment_trade_no']);
	$input->SetTotal_fee($totalFee); //订单总金额(分)
	$input->SetRefund_fee($refundFee); //退款金额(分)
	$input->SetOut_refund_no($out_request_no);
	$input->SetOp_user_id(\WxPayConfig::MCHID);
	//printf_info(WxPayApi::refund($input));
	//exit();
} else if(isset($recordInfo["order_no"]) && $recordInfo["order_no"] != "") { //商户订单号
	$input = new \WxPayRefund();
	$input->SetOut_trade_no($recordInfo["order_no"]);
	$input->SetTotal_fee($totalFee); //订单总金额(分)
	$input->SetRefund_fee($refundFee); //退款金额(分)
	$input->SetOut_refund_no($out_request_no);
	$input->SetOp_user_id(\WxPayConfig::MCHID);
	//printf_info(WxPayApi::refund($input));
	//exit();
}

$result = \WxPayApi::refund($input);
//print_r($result);exit;

/*
Array
(
	[appid] => wxc01a087549f319e6
	[err_code] => ERROR
	[err_code_des] => 订单已全额退款
	[mch_id] => 1484032972
	[nonce_str] => VawgJ2T8hGObZLgH
	[result_code] => FAIL
	[return_code] => SUCCESS
	[return_msg] => OK
	[sign] => 6CB67B53250E0D1D740974CD0FDDFCA1
)
*/

if ($result['return_code'] == 'SUCCESS') {
	if ($result['result_code'] == 'FAIL') {
		$this->error('微信退款失败发生错误: '.$result['err_code_des']);
	}
	$msg = '退款成功，'.$refund_fee.'元退款到用户微信钱包';
} else if ($result['return_code'] == 'FAIL') {
	//print_r($result);exit;
	$this->error('微信退款发生错误: '.$result['return_msg']);
}
			//foreach($result as $key=>$value){
			//    echo "<font color='#f00;'>$key</font> : $value <br/>";
			//    exit;
			//}
		} else {
			$this->error('支付方式非法，无法退款');
		}
		//==========支付宝和微信退款操作 END

		//=====更新订单状态
		$refund_status = 8;
		if ($recordInfo['refund_fee']) {
			$total_refund_fee = $recordInfo['refund_fee'] + $refund_fee;
			if ($total_refund_fee == $recordInfo['total_fee']) { //已全额还款
				$refund_status = 9;
			}
		}

		//更新报名记录信息
		$data = [
			'refund_status'	=> $refund_status, //订单退款状态
			'refund_fee'	=> $total_refund_fee, //退款金额叠加
			'refund_time'	=> $this->ts,
		];
		if ($refund_status == 9) {
			$data['signup_status'] = 8; //报名状态
		}
		$result = $this->recordDao->baseUpdateData($recordId, $data);

		if ($channel == 1) { //后台管理员退款
			//生成退款记录
			$data = [
				'channel'			=> $channel, //订单退款渠道
				'status'			=> 2, //订单退款表状态
				'record_id'			=> $recordId,
				'kid'				=> $kid,
				'uid'				=> $recordInfo['uid'],
				'pwuid'				=> $recordInfo['pwuid'],
				'username'			=> $recordInfo['username'],
				'create_time'		=> $this->ts,
				'total_fee'			=> $recordInfo['total_fee'],
				'refund_fee'		=> $refund_fee,
				'order_no'			=> $recordInfo['order_no'],
				'out_request_no'	=> $out_request_no,
				'refund_reason'		=> $refund_reason,
				'admin_uid'			=> $this->adminuid,
				'admin_username'	=> $this->adminname,
			];
			$this->recordRefundDao->baseAddData($data);
		} else if ($channel == 2) { //用户申请退款
			$data = [
				'status'			=> 2, //订单退款表状态
				'out_request_no'	=> $out_request_no,
				'refund_fee'		=> $refund_fee,
				'refund_time'		=> $this->ts,
				'refund_method'		=> $recordInfo['pay_method'],
				'admin_uid'			=> $this->adminuid,
				'admin_username'	=> $this->adminname,
				'refund_reason'		=> $refund_reason,
			];
			$this->recordRefundDao->baseUpdateData($refundId, $data);
		}

		$this->success($msg);
	}

	private function _build_order_no($uid) {
		return 'FSR'.date('ymdhis').rand(10, 99).str_pad($uid, 6, "0", STR_PAD_LEFT);
	}

}